home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
graphics
/
3dvect30.arj
/
README.DOC
< prev
next >
Wrap
Text File
|
1993-11-18
|
30KB
|
577 lines
3d Vectors Source 3.0
Date of release - Dec 1/93
Written by: John McCarthy
1316 Redwood Lane
Pickering, Ontario.
Canada, Earth, Milky Way (for those out-of-towners)
L1X 1C5
Internet/Usenet: BRIAN.MCCARTHY@CANREM.COM
Fidonet: Brian McCarthy 1:229/15
RIME/Relaynet: ->CRS
Home phone, (416) 831-1944, don't call at 2 am eh!
^^^ has been changed to (905) 831-1944!!!
God, this package is getting big...
Routines to be used by all for anything, just send me a copy of what
you've accomplished (final product), or at least send me a postcard from
someplace near where you live.
Many thanks to: Razor - for providing source for their demo. This gave
me the idea of how to draw polygons in the first place.
Mode X routines - Matt Pritchard
Protected Mode Header - Tran
Bitmap X-mode Scaling routine - John A. Slagel
Technical support - Robin Ward
(in no defined Danny Hawrysio
order) Robert Johnston
Ciaran Gultniers
Mark Rostek
Shawn Knight
Sebastian Dwornik
Adam Kurzawa
Adam Johns
Ciaus Tenche
Peter Gruhn
Sean Palmer
Alan Illeman
Rob Czuppon
Food provided by - My Mommy
As noted above, this file would not be possible without other people
giving away their source code. I continue the tradition of "knowledge is
power" and give this away. Most people who see this will never do a damn
thing with it but look at it and say "uh, so, what next?" so I don't want
you to register or anything dumb like that. By the way, people who want
money for crappy shareware progs can rot in hell. But if you do make a
commercial game, and make billions, at least send me a postcard from
the Bahamas ok! Like I'm not going to refuse a cheque if you make
something commercial, but like I said, only 1 in a million may actually
have the time/effort/patience/guts/brains to make a commercial game.
The original Mode X routines have been modified to support protected
mode. Many thanks Matt Pritchard for the X-Mode knowledge. I hope you
don't mind my changing your routines. Matt Pritchard can be reached at
P.O. Box 140264, Irving, TX 75014 USA.
The protected mode header has been supplied by TRAN and can be reached on
Sound Barrier BBS (718)979-6629. I have included all of TRANs protected
mode package because I really hate getting code from someplace and not
getting the support for it. I make no claim to any of this code, I
simply want to supply you with all the info to effectively work with this
3d vector package. TRAN implies that you can reach him on internet at
tran@phantom.com
The bitmap scale routine has been supplied by John A. Slagel. Thanks to
you as well where ever you are. The scale routine now supports
transparent bitmapping. As of this writing, John A. Slagel's internet
access has been canceled and I have no other address for him.
If you want the original non-protected mode Vector routines, I can dig
them up for you if you send me a disk or something. But first, ask
yourself, "Why would anyone want to go back to segmented coding?" If
you still want those routines, hit self on head with nearest blunt
object and re-ask question. (Many thanks TRAN)
Routines are heavily optimized for 3d vectors. Any code/routine that
slow is not intended to be used with animation and has been written to
simply get the job done. You will know which routines are slow/fast once
you look at the code.
I don't apologize for the lack of effective documentation or example
programs as this code was written for my own use. I would like to spend
more time writing code than writing docs. I also don't apologize for the
lack of universality of code execution. For example, Matts xmode code is
callable from C but mine isn't. Some of the routines must have registers
set up before entry and some require memory to be set up. U figure which
is which. It usually says at the begining of the routine. Once again,
making everything callable from C slows things down and this is what I
wanted to avoid. Speed is the key considering it is for my own use.
You must have a 386 to run this. If you only have a 286, get a job and
buy a real machine!
Also, I really hate people who give away their "source" code but actually
only give away the object file. If these people are so embarassed about
their crappy code then we don't want your crappy object file. Give away
all or nothing.
It would be really nice if I got a postcard from some place near where you
live.
Some files in this zip:
main.asm ; example program to show vectors
3d1.asm ; 3d vector routines by John McCarthy, fast sort method
3d2.asm ; 3d vector routines by John McCarthy, full sort method
xmode.asm ; xmode routines by Matt Pritchard
xmouse.asm ; xmode/protected mode mouse routines
pmode.asm ; protected mode routines by TRAN
file.asm ; pmode file routines by TRAN
argc.asm ; command line argument scanner by TRAN
stars.asm ; plot stars
font.asm ; screen setup routines
xmode.inc ; files defining externals for linkage
xmouse.inc ; with above asm files
pmode.inc ; example: if you want to use some routines/data
3d.inc ; from xmode.asm, use:include xmode.inc
file.inc
argc.inc
stars.inc
font.inc
xscale.inc ; bitmap scaling routines
math.inc ; math functions for 3d.asm
sin.inc ; data tables for math functions: math.inc
arctan.inc ; inverse tan function tables: math.inc
vars1/2.inc ; variables for 3d.asm routine
equ.inc ; list of constants
shading.inc ; arctan shading table
macros.inc ; macros used throughout
qb.zip ; qb quickbasic programs to generate sin and arctan tables
modex104.zip ; (some of the) original files from Matt's modex104.zip
Some bugs fixed for 2.1:
Mouse routine draw_bitmap fixed (start of bitmap is x and y). Fixes crash
Also, the mouse resolution has been divided by two to stop that dang two
pixel movement!
Many bugs fixed in Xmode.asm conversion from segmented mode to protected
mode. Too many protected mode bug fixes to list.
Also added some palette fading routines to xmode.asm
The big change is the new method of sorting surfaces. Before, objects
were sorted first, then surfaces within objects were sorted. Now, drawing
an object simply draws the surfaces in memory and then ALL surfaces
are sorted as a group. This now allows small objects to go inside larger
objects. This is not possible in 3d1, small objects will disappear. The
3d1 file is faster but the 3d2 file has greater flexability with objects.
The old file is 3d1.asm while the full sorting file is 3d2.asm. To use
you must call sort_list and drawvect after makeobjs (if using 3d2 - the
full sort method). See main1 and main2 for examples. To give you the
speed difference between the two, the calculation for a bubble sort is
(n^2+n)/2 for number of times routine will sort. In 3d1 - 30 objects with
30 sides will take 465 sorts * 30 objects + 465 to sort those objects is
= 14,415 loops. But 3d2 uses the basic 30*30 sorts. Therefore,
(900^2+900)/2 = 405,450 loops! You can use 3d2 in portions and still get
the speed of 3d1 if you know certain objects will be far or near (eg land
scapes and stars are always far) and this can provide you with the speed
and versatility of objects going inside one another. The only difference
between 3d1 and 3d2 is the sort method - full objects then surfaces (3d1),
or all surfaces together (3d2).
Also made it possible to now have points (single dots) and bitmaps as
part of an object. You no longer need to make a bitmap it's own object
but can now have it as part of another object. It is still possible to
have bitmaps as their own objects (for explosions and bullets). See
sphered cube and regular sphere in example file.
Optimizations for 3dvect22:
Better make1obj routine now uses ematrix more efficeintly by only
calculating matrix x,y and z as needed - makes better use of cpu time
when there are many objects off screen (behind camera or too far lft/rgt
up/dwn)
Added more math functions
Optimized erotate when usez = no
Changes for 3dvect23: Aug 10/93
Implemented new pmode.asm code by TRAN. This replaces the start32 code
and allows 3dvect to be run with memory managers like HIMEM and EMM386.
Many thanks to TRAN! Note: Maximum speed is still found with no memory
managers - ei. raw memory. Change all int 30h's to int 33h's.
Removed some common routines from 3d1 and 3d2 and put them in poly.inc to
avoid duplicate copies of routines.
Also added to xmode.asm routines to turn off the screen to stop flicker
when changing into xmode
Updated TGA2ICON program so it will function with the new pmode header
and can operate with those nasty memory managers.
I am currently writing this from my living room floor where I have been
laying for the last month due to a herniated disc in my lower back - fun!
Additions for 3dvect24: Aug 29/93
The main addition for version 2.4 is the IRQ routine that co-ordinates
itself with the routine updvectors. The IRQ increments the byte
traces_past every time a vertical retrace occures (regardless of what
the vector routines are doing) and the routine updvectors (get it, up the
vectors - d=the, like the poor people say) anyway, updvectors uses this
value to make the objects/animation "jump" ahead and skip frames. the
slower the computer or the greater number of objects there are on the
screen, the higher the value traces_past will be after updating the
screen. Therefore, if you write your own game/animation, use this value
to determine how fast the game should go - the IRQ is timed to match the
vertical retrace so every time one passes by, traces_past gets +1. I have
two interrupts - a protected mode IRQ and a real mode IRQ. I did it this
way so that if you want to add music or whatever, you can use either type
of IRQ. Both add 1 to traces_past. Also, I have timed the IRQ to be
close to the vertical retrace time but I don't know if I have done it
correctly. If you notice that the out dx,al is not the way to go about
it, drop me a line with the correct method of setting the 8253 timer.
The value of traces_past will be from 1 to whatever (never 0 after trace)
I also fixed a small bug in the updvectors routine - which is now called
updvectors2, called by "updvectors".
I have also had a back operation to fix that herniated disc and am now
sitting upright at my computer. So I have this message for you: Sit up
straight at all occasions, bend from the knees, get two people to lift
a heavy object, don't be macho,stand straight at all times,walk straight,
don't slouch when driving, don't over excercise, don't prop your head up
with your arm when watching TV, (put adjective here) straight. TAKE CARE
OF YOUR AMAZING MOTION MACHINE - YOUR BACK. Learn the easy way from
someone who learnt the hard way - we're not invincible. STRAIGHT STRAIGHT
STRAIGHT! STRAIGHT! STRAIGHT! STRAIGHT! There, I'm done.
Some bugs fixed for 2.5:
Fixed the timer IRQ to have OUT 43h,AL (You'll never know the difference
but I thought it would be a nice gesture)
I have also ripped a routine from someplace else to time the vertical
retrace and set the irq to this value. This replaces the static variable
with a more accurate calculation for each computer's irq timing.
I also added a total retrace counter called "frame_number" which counts
from the begining of any animation so you can, let's say at 2.5 minutes
into it, perform a certain function. The counter is only reset when
reset_raster_count is called (begining of new animation sequence).
I have also changed the math routine setsincose so that if you are not
using z rotations, you won't need to reset eyeaz to 0. (Can be anything)
This really doesn't increase speed much though.
I optimized some of the imuls with a pre-calculated table. Just to remind
you: Changing video modes can occure within the program, but you can
only change the vertical size, not the horizontal size (eg swap between
320x400 mode and 320x200 mode, or 360x480 mode and 360x240 mode) You
would only need to adjust the clipping limits and the make3d constants to
change modes while the program is executing. Re-assembley would be
required if you wanted to change into a different x-width mode.
Fixed the xmouse.asm routine plot_mouse. It was not using an earlier
xmode bitmap change.
Robert Johnston now has the correct spelling to his name.
By the way, the mouse is supposed to look like that! Call plot_mouse
without any page flipping if you want a regular mouse that remembers what
is behind it.
Help required for 2.6:
I am having a problem with assembleys>65536 bytes. A description should
be found at the bottom of main1.asm. Call me voice of you know how to fix
it. Heck, if you know how to fix it, call today. Note:Sept 26,problem
solved!
Additional .asm files for 2.7:
A file has been added to put stars in the background. Stars.asm only
calculates the positions of stars that will be on or close to the screen.
The routine has two assembley modes - full stars or half stars. The half
stars mode plots stars that are above the 0y axis. This allows you to
have a flat surface (airfield/horizon) without calculating the positions
of stars below the screen. The routine is called show_stars.
I have added a macro to the file macros.inc to multiply by a constant.
The macro is used as cmul result, value, constant. eg cmul eax,ecx,320.
Only some values are supported but this will change as more constants
are required. This replaces a few lines of code in the make3d routines
so ratiox and ratioy imul's can be used by the user (you) without having
to import the code from math.inc. I also fixed a tini-eeni-wini bug
in the non-fast imul routine - not that you care or anything...
God, I can't wait to get a 586...
I have also solved (?) the problem with files>64k not working,I have made
all 16 bit indexes to 32 bit indexes. The only remaining problem/drawback
is that the linking order must be such that the irq assembley follows the
protected mode header, eg: TLINK /3 pmode irq xx xxx xx xx. I don't know
why the irq stuff doesn't work if is in the>64k block, maybe because it
has 16 bit real mode code in it or something, who knows...Just link it as
I have and you can do anything else you want in the 32 bit code segment.
Because of the above, I have moved the variables traces_past and
frame_number from 3d.asm to irq.asm. If you need the computer speed/frame
speed, you will have to have irq.inc in your assembley. Don't look for
these variables in vars1.inc or vars2.inc anymore, they have been moved
to irq.asm.
Removed more common routines from 3d1 and 3d2 and put them in poly.inc.
John says hi to Sebastian...
Optimizations for 2.8:
Stars routine runs a tad faster.
A better method of moving that cube at the end of main1 example has been
implemented (set counter and xadds). This main1 and main2 are just
example files to show some of the features.
Additions for 2.9: Sept 28,'93
I just had a brainstorm on how to calculate the 3d stars considering the
stars are at a constant distance from the camera. The variable
perfect_stars has been added to allow the stars routine to calculate non
perfect 3d stars. This makes the routine much faster, while it basically
looks the same. This is possible since the stars are always at a
constant distance from the camera.
I've also added more macros to the cmul macro. That is, more multiply
by constant macros...
Ok people, how come I haven't gotton any postcards yet? Does nobody read
this code? Like, it only cost's 50 some odd cents for a stamp. I mean,
tell me what the weather is like where you are, or something about the
local news events.
Additions for 2.A (hex): Oct 1, '93
Variables xxxfinal[] have been added to the movement/rotate routines to
ensure correct final placement of an object. This was necessary due to
errors when multiple additions of speed*time did not equal the actual
requested final position. So, every time you change the anglular or
linear velocity, the variables final position must be set to tell
updvectors where that final position is. If you do not want to calculate
the final positions yourself, two routines have been supplied to do it
for you: set_finall - for linear calculations, and set_finala for angular
calculations.
Added a routine called twist_si. This sets the objects rotational
velocity based on a 32 bit input. Similar to move_si routine.
When using twist_si or move_si, try to keep the time small.
eg: <1000 frames. this will prevent a "jump" when the object finally
stops moving/rotating. if you want large time constants, call set_finall
or set_finala after calling move_si or twist_si respectivly. This will
re-calculate the final position based on large time/decimal error loss
and prevent the object from "jumping" at the end of it's cycle/count.
OR: call move_si or twist_si in sections, eg call it first as you would
normally (with correct time/distance/angles loaded) then, half way to
it's destination, call the routine again (with time/2). This will re-cal
the speed better and will also prevent that "jump". (Did you get that?)
We will note that my number (as of Oct 4) gets changed to the 905 area
code - (905) 831-1944.
Some routines added - Point_it, points object si at object di. This
only affects the x and y angles, the z angle can still provide spin.
Point_to points object si to location ebx,ecx,ebp
Point_dir routine points object si in the direction it is moving.
Set_speed routine does the opposite of the above routine. It sets the
speed of the object to the direction it is pointing. si = object,
ebp = speed, di = lcount. (lcount = linear counter, object stops when 0)
Point_time routine points object si to ebx,ecx,ebp in di frames
I managed to get my Suzuki GS1150 up to 240km/hr on the 401 today...
Features added to 2.B: Oct 6, '93
Shading like the pro's: (Wait a minute, isn't that me?)
Routines added:
pre_cal_lambert - scan object si and calculate surface normals
calc_normal - from 3 points, returns normal vector ebx,ecx,ebp
lambert - calculate surface normal rotation maxtrix for object si
set_up_all_lambert- scans objects from si to di and calls pre_cal_lambert
lrotate. - given normal for surface, figures out intensity
I finally bought a book on assembley language today. God, there's all
kinds of stuff I didn't know this computer can do. Like xlat...bt...
I've included some old screen set up routines - font.asm and font?.inc
There not really font routines, just screen setup routines.
Also made the vector sort a little more accurate.
Many, many, many additions for 3.0: Dec 1, '93
THE OBJECT FORMAT HAS BEEN CHANGED! Changes include addition of 25 words
at the beginning of the object to accomodate future revisions. But the big
change is that all points are now point+1. eg what used to be 0,1,2,0 is
now 1,2,3,1. This gives the user access to point 0, which is the objects
center of gravity. (point 0,0,0). The new format for surface definition
is:
dw commands, texture1,texture2,colour1,colour2, connections, [0,0,0]
where the commands determine what the surface is, eg:polygon, texture,
bitmap, point, line, along with the visibility and iteration commands.
While texture1 and color1 determine what the polygon will look like on the
first side, txt2 and col2 determine what the other side will look like.
Joystick routines added - see joystick.asm. The routines use the xmode
font stuff but that could be removed and this code could be transported
anywhere.
Some optimizations in math.inc (thanks to my new assembler book, Oooo...)
I finally found out how to make a MAKE file.
We will notice my internet access has been corrected.
Optimized/fixed the calc_angles routine (not that you'll care or anything)
Iterations added to objects. Now object surfaces can have surfaces within
surfaces within surfaces within surfaces...Example: a building has a main
wall with many windows on it, on the windows there is a sign, on the sign
there is a bug - if the sign isn't visible, don't plot the bug - if the
window isn't visible, dont plot the sign (or the bug) - if the main wall
isn't visible, don't plot anything. This allows objects to be very very
detailed without wasting CPU time. Iterations save MEGA cpu time!!!
Another sort method has been added - 3d3.asm. This method uses parts from
both 3d1.asm and 3d2.asm. How it works - the objects are sorted as
individual objects until they become close to one another (set by
collision tolerence value) then they get sorted as one object. This allows
objects to go through one another (and still be sorted correctly) yet
avoids the CPU intensive sorting of hundreds of sides. If you set the
tolerence value to 0, the code will run just like 3d1.asm, if you set it
to 1billionx, the code will run like 3d2.asm - somewhere in the middle the
two sort methods mix. (Note: 3d1.asm is still the fastest)
A routine has been added to allow the user to scan a file for a "[MARKER]"
or magic word. The _findmarker routine scans a file and returns an offset
(32 bit) in the file as to where the marker was found. This can be used
to load in mods/gifs and data from the end of the program instead of
having a seperate data file(s). This method is similar to the method used
in demos like UNREAL.EXE and CD2.EXE. It could also be used to store data
in or modify the original program. This is not really related to 3d vector
programming though.
Relative surface colour option can use the intensity from the previous
surface. This relieves the CPU from performing repetative surface normal
calculations. Eg: set the first surface to gourad/lambert shading and set
all other surfaces with the same normal (angle) to use this intensity. The
object command to use the previous surface colour is 4096.
Another method for testing if a side is visible has been implemented. Now,
as well the surface being counter-clockwise, you can also test if all the
points are on the screen. This can be either combined with the counter
clockwise test or used on it's own. I don't what good it is yet though...
Maybe useful when combined with iterations? The test works even
if a large polygon covers the screen (like the side of a large building)
I have now made 3d1,3d2 and 3d3 all use the same animation format: eg call
init_tables before an animation then call makeobjs during the animation.
This is the same method for all 3 sorting types. Although these routines
call different routines in each file, they all end up doing the same
thing.
I actually found a bug in this thing! (yes one little bug) - fixed the
arctan function.
Extraced the clipped_line routine so you can use it anywhere. Clipped_line
routine draws from dx,cx to ax,bx colour bp, but does it with cartesian
cords - eg 0,0 is screen center,also updates clearing width/height if used
and clips to borders (of course).
Palette cross referencing option added for each object. Lets say you've
got 6 spaceships on the screen but you want them each to have a different
colour scheme. Set the offset dword of [palxref] to point to a cross
reference palette. This way, many on-screen objects can use the same
shape data but each can have a different colour scheme.
I got my 486DX66 today...(Friday Nov 5/93)
Due to popular demand, the camera is now the zero'th object!! Therefore,
all of your objects start a location 1 (1 = 1st object, 2 = 2nd object...)
The old way had the camera as the last object. So, to move the camera
to location x,y,z in di frames: load up ebx,ecx,ebp as location to move to
load di with time to get there, load si = 0 (cameraobject=0) and call
move_si.
The vector matricies have been truncated to 16 bits from 32 bits. The
accuracy of the code however, remains the same as before.
Small, tini-weeni bug fixed in polyfill. I am no longer using doubleword
transfers to the VGA. This should stop people having their monitors
destroyed - (just kidding) It removes those eggs.
And yet another option! 1/4 scaled fuzzy bitmaps (for lack of a better
name). These are scalable, non-rotatable bitmaps just like the ones you've
seen before (option 32) but only every 4'th pixel is sampled. This has
the advantage of faster plotting of bitmaps that don't require a lot of
accuracy - like explosions and smoke. To invoke this new type of bitmap,
just use option 33 (32+1) in either the object definition or in userotate.
(note: if used in object, bitmap is part of object. if used in userotate,
entire object is one big bitmap - like I said, good for explosions)
Holly Kamolly, this thing is getting big...
All surface/polygon options have now been set to defines. Look in the equ
file to see what options there are. This now replaces using 512+256+2+...
in your object. (makes understanding them easier) The new defines are:
excerpt from equ.inc: current list of commands and texture options
; texture options (texture1&2)
wavey equ 1 ; sine wave surface
shade equ 2 ; lambert shaded surface
inverse equ 4 ; inverse shading
glow equ shade+inverse
last equ 8 ; colour is same intensity as previous surface
texture equ 16 ; texture mapped surface
; surface types (command)
point equ 32 ; surface is a point
line equ 64 ; surface is a line
himap equ 128 ; scalable, non-rotatable, hi quality bitmap
lomap equ himap+1 ; scalable, non-rotatable, lo quality bitmap
; surface commands(command)
iterate equ 256 ; generate iteration below if side visible
; visibility determination methods (command)
both equ 1 ; always visible, no matter side
double equ 2 ; double sided surface, other side has texture2 and colour2
onscr equ 4 ; is polygon on screen?
check equ 8 ; check if polygon is on screen/counter-clockwise, but don't plot
to be used in the format:
dw commands,texture1,texture2,colour1,colour2, connections, [0,0,0]
The objects now have user-difinable resolutions. Look at the objects.inc
file to see how I have implemented this. The first dd is the resolution
at which the next offset is visible at. Successive resolutions are
visible at farther distances. The only object I have implemented with
a different resolution is that bitmapped cube thingy. Notice as it gets
farther away, the chrome balls turn into single pixels. The end flag
for "this is the last resolution" is -1.
Version 3.1:Texture mapping, PCX decoding, object Hierarchy, real time irq
palette fading, superfast log table multiply, joystick routines